#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    subProductModel = new QStandardItemModel;
    suppliersModel = new QStandardItemModel;
    solutionModel = new QStandardItemModel;
    ui ->solutionTable->setModel(solutionModel);
    ui ->solutionTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    solutionModel->setColumnCount(2);
    processBase = new DataBase();    
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::loadBase(DataBase *newBase){
  //dopisac funkcje setupModel ;)
  Product temp;
  Supplier supTemp;
  int position;
  QModelIndex index;
  subProductModel->clear();
  suppliersModel->clear();
  subProductModel->setColumnCount(3);
  suppliersModel->setColumnCount(5);
//  subProductModel->setRowCount(newBase->countProducts());
  for(int i = 0;i<newBase->countProducts();i++){
        temp = newBase->getProduct(i);
        position = subProductModel->rowCount();
        subProductModel->insertRow(position);
        subProductModel->setData(subProductModel->index(position,0),QVariant().fromValue(temp.getName()));
        subProductModel->setData(subProductModel->index(position,1),QVariant().fromValue(temp.getQuantity()));
        subProductModel->setData(subProductModel->index(position,2),QVariant().fromValue(temp.getUnit()));

        for(int j=0;j<temp.countSuppliers();j++){
            supTemp = temp.getSupplier(j);
            position = suppliersModel->rowCount();
            suppliersModel->insertRow(position);
            suppliersModel->setData( suppliersModel->index(position,0),QVariant().fromValue(supTemp.getName()) );
            suppliersModel->setData( suppliersModel->index(position,1),QVariant().fromValue(temp.getName()) );
            suppliersModel->setData( suppliersModel->index(position,2),QVariant().fromValue(supTemp.getCost()) );
            suppliersModel->setData( suppliersModel->index(position,3),QVariant().fromValue(supTemp.getProductionTime() ) );
            suppliersModel->setData( suppliersModel->index(position,4),QVariant().fromValue(supTemp.getQuantityAvalaiblePerDay()) );
        }

  }

}
void MainWindow::openDatabase(){
    QString fileName = QFileDialog::getOpenFileName(new QFileDialog, tr("Open File"),
                                                    "",
                                                    tr("Plik danych (*.xml)"));

   // delete ourBase;
  //  ourBase =0;
    ourBase = new DataBase(fileName) ;
    loadBase(ourBase);
}

void MainWindow::saveDatabase(){
    //processBase->
}

void MainWindow::editProduct(){
    productDialog *dialog = new productDialog(ourBase);
    dialog->show();
}

void MainWindow::editSubProducts(){
    subProductDialog *dialog = new subProductDialog(subProductModel);
    dialog->show();
}
void MainWindow::editSuppliers(){
    suppliersDialog *dialog = new suppliersDialog(suppliersModel);
    dialog->show();

}
void MainWindow::editTabu(){
    setTabu *dialog = new setTabu();
    connect( dialog,SIGNAL( saveTabu(int,int,int,int,int,int,int,int)),
             this, SLOT(on_saveTabu(int,int,int,int,int,int,int,int)));
    connect(this, SIGNAL(tabuParam(int,int,int,int,int,int,int,int)),
            dialog, SLOT(on_tabu_param(int,int,int,int,int,int,int,int)) );
    emit tabuParam(_iter,  _iterImprov, _improv, _tabuLength,
                   _iterJump,_iterLocalJump, _kara, _nagroda);
    dialog ->show();
}

void MainWindow::setProcessBase(){
    processBase->clearProducts();
    for(int i=0;i<subProductModel->rowCount();i++){
        Product temp;

        temp.productName = subProductModel->data(subProductModel->index(i,0)).toString();
        temp.unit = subProductModel->data(subProductModel->index(i,1)).toString();
        temp.quantity = subProductModel->data(subProductModel->index(i,2)).toInt();

        for(int j=0;j<suppliersModel->rowCount();j++){
            if( suppliersModel->data(suppliersModel->index(j,1)).toString() == subProductModel->data(subProductModel->index(i,0)).toString() ){
                temp.addSupplier(suppliersModel->data(suppliersModel->index(j,0)).toString(),
                                 suppliersModel->data(suppliersModel->index(j,1)).toInt(),
                                 suppliersModel->data(suppliersModel->index(j,2)).toInt(),
                                 suppliersModel->data(suppliersModel->index(j,3)).toInt()
                                 );
            }
        }
        processBase->addProduct(temp);
    }
    suppliersModel->clear();
    subProductModel->clear();
    loadBase(processBase);
}

void MainWindow::on_START_clicked()
{
  setProcessBase();
  _firstSolution.fill(0,processBase->countProducts());
  algTabu = new workerThread(processBase,  _iter,  _iterImprov, _improv, _tabuLength,
                             _iterJump,_iterLocalJump, _firstSolution, _kara, _nagroda);
  connect(algTabu->algorithm ,SIGNAL(step(int,QVector<float>,QVector<int>)),
          this,SLOT(on_algStep(int , QVector<float> , QVector<int>))  );
  solutionModel->clear();
  solutionModel->setColumnCount(2);
  algTabu ->run();
}
void MainWindow::on_algStep(int number,  QVector<float> values,QVector<int> bestSolution){
    Product temp;
    Supplier tempSup;
    for(int i=0;i<subProductModel->rowCount();i++){
        solutionModel->insertRow(i);
        temp = processBase->getProduct(i);
        solutionModel->setData(solutionModel->index(i,0),QVariant(temp.getName()));//subProductModel->data(subProductModel->index(i,0)));
        tempSup = temp.getSupplier(bestSolution[i]);
        solutionModel->setData(solutionModel->index(i,1),QVariant(tempSup.getName()));
    }
    ui->koszt->setText(QString::number(values[values.size()-1]));
    ui->czas->setText(QString(bestSolution[bestSolution.size()-1]));
    ui->solutionTable->show();
}
void MainWindow::on_saveTabu(int iter, int iterImprov, int improv, int tabuLength, int iterJump, int iterLocalJump, int kara, int nagroda){
     _iter = iter;
     _iterImprov = iterImprov;
     _improv = improv;
     _tabuLength = tabuLength;
     _iterJump = iterJump;
     _iterLocalJump = iterLocalJump;
     _kara = kara;
     _nagroda =  nagroda;

}
